package org.abc.manager 
{
	import com.bit101.components.Accordion;
	import com.bit101.components.Component;
	import com.bit101.components.FPSMeter;
	import com.bit101.components.Window;
	import com.demonsters.debugger.MonsterDebugger;
	import com.junkbyte.console.Cc;
	import flash.events.KeyboardEvent;
	import flash.geom.Rectangle;
	import flash.ui.Keyboard;
	
	import flash.display.Stage;
	
	import org.abc.uiCore.AbcDispatcher;
	import org.abc.consts.EventConst;
	import org.abc.uiCore.vo.EventVo;
	import org.abc.uiCore.vo.TraceVo;
	import org.abc.interfaces.IDebug;
	
	/**
	 * 
	 * 单例模式类
	 * @describe		...
	 * @author			Mr.zheng
	 * @time 			2011-9-18 14:00
	 */
	public class DebugManager implements IDebug
	{
		private static var _instance:DebugManager = null;
		public function DebugManager(single:Single){
			
			if(single == null)
			{
				throw new Error("Can't create instance , Single is Null!");
			}
		}
		/**
		 * 单例引用
		 */
		public static function get instance():DebugManager
		{
			if(_instance == null)
			{
				_instance = new DebugManager(new Single());
			}
			return _instance;
		}
		
		//start-----------------------------------------------------------------------------
		private var _gameStage:Stage;
		private var _debugWindow:Window;
		
		protected var debugAc:Accordion;
		protected var fps:FPSMeter;
		
		/* INTERFACE org.abc.interfaces.IDebug */
		
		public function init(gameStage:Stage):void 
		{
			_gameStage = gameStage;
			
			AbcDispatcher.addEventListener(EventConst.TRACE_INFO_START, onTraceInfo);
			
			initCc();
			initMonsterDebugger();
			initDebugPanel();
		}
		
		public function trace(...args):void 
		{
			Cc.log.apply(null,args);
		}
		
		public function inspect(obj:Object):void 
		{
			Cc.inspect(obj);
		}
		public function traceCh(channcel:*, ...args):void 
		{
			Cc.infoch(channcel,args);
		}
		/* public function */
		
		/* private function */
		private function initCc():void {
			Cc.startOnStage(_gameStage, "`"); // "`" - change for password. This will start hidden
			Cc.visible = false; // Show console, because having password hides console.
			
			Cc.config.commandLineAllowed = true; // enable advanced (but security risk) features.
			Cc.config.tracing = true; // Also trace on flash's normal trace
			Cc.config.remotingPassword = null; // Just so that remote don't ask for password
			Cc.remoting = true; // Start sending logs to remote (using LocalConnection)
			
			Cc.commandLine = true; // Show command line
			
			Cc.height = 220; // change height. You can set x y width height to position/size the main panel
		}
		private function initMonsterDebugger():void{
			MonsterDebugger.initialize(_gameStage);
		}
		private function onTraceInfo(e:EventVo):void 
		{
			var traceVo:TraceVo = e.data as TraceVo;
			switch (traceVo.type)
			{
				case TraceVo.TRACE:
					Cc.info(traceVo.traceObj);
					break;
				case TraceVo.TRACE_CH:
					Cc.infoch(traceVo.channelName, traceVo.traceObj);
					break;
				case TraceVo.TRACE_INSPECT:
					Cc.inspectch(traceVo.channelName, traceVo.traceObj);
					MonsterDebugger.inspect(traceVo.traceObj);
					break;
				default:
			}
		}
		/**
		 * 调试面板
		 */
		private function initDebugPanel():void 
		{
			_debugWindow = new Window();
			_debugWindow.title = "debug test";
			
			debugAc = new Accordion();
			addChildToDebugWindow(_debugWindow, debugAc);
			fps = new FPSMeter();
			addChildToDebugWindow(debugAc.getWindowAt(0), fps);
			debugAc.getWindowAt(0).title = "显示帧频";
			debugAc.getWindowAt(1).title = "调试数据";
			
			_gameStage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
		}
		
		private function onKeyDown(e:KeyboardEvent):void 
		{
			switch (e.keyCode) 
			{
				case Keyboard.ENTER:
					if (_debugWindow.parent) {
						_gameStage.removeChild(_debugWindow);
					}else {
						_gameStage.addChild(_debugWindow);
					}
				break;
				default:
			}
		}
		/**
		 * 添加子对象
		 * @param	parentComponent
		 * @param	childComponent
		 */
		protected function addChildToDebugWindow(parentComponent:Component,childComponent:Component):void {
			parentComponent.addChild(childComponent);
			checkSize(parentComponent,childComponent);
		}
		/**
		 * 设置大小 
		 * @param parentComponent
		 * @param childComponent
		 * 
		 */
		private function checkSize(parentComponent:Component,childComponent:Component):void {
			var rec:Rectangle = childComponent.getRect(parentComponent);
			if (rec.x + rec.width > parentComponent.width
			||rec.y + rec.height > parentComponent.height) {
				parentComponent.width = rec.x + rec.width;
				parentComponent.height = rec.y + rec.height;
				if (parentComponent.parent||parentComponent.parent is Component) {
					checkSize((parentComponent.parent as Component),parentComponent);
				}
			}
		}
	}
}
class Single{}